package org.filetransfer.file_transfer_java_backend.config;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.io.IOException;
import java.lang.reflect.Method;

@Component
@RequiredArgsConstructor
@Slf4j
public class AuthCheckFilter extends OncePerRequestFilter {

    private final RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    protected void doFilterInternal(@NonNull HttpServletRequest request,
                                  @NonNull HttpServletResponse response,
                                  @NonNull FilterChain filterChain) throws ServletException, IOException {
        
        try {
            // 获取当前请求对应的处理方法
            HandlerExecutionChain handlerChain = requestMappingHandlerMapping.getHandler(request);
            
            if (handlerChain != null && handlerChain.getHandler() instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handlerChain.getHandler();
                Method method = handlerMethod.getMethod();
                Class<?> controllerClass = handlerMethod.getBeanType();
                
                // 检查方法或类是否有 @RequireAuth 注解
                boolean requireAuth = method.isAnnotationPresent(RequireAuth.class) || 
                                    controllerClass.isAnnotationPresent(RequireAuth.class);
                
                if (requireAuth) {
                    // 检查是否已认证
                    if (SecurityContextHolder.getContext().getAuthentication() == null || 
                        !SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
                        
                        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                        response.setContentType("application/json;charset=UTF-8");
                        response.getWriter().write("{\"error\":\"需要身份验证才能访问此API\",\"code\":403}");
                        return;
                    }
                }
            }
        } catch (Exception ex) {
            log.debug("无法获取处理方法信息，继续处理请求: {}", ex.getMessage());
        }
        
        filterChain.doFilter(request, response);
    }
}
